﻿/**
 *	(C) 2014 Yuanjj
 *
 *	define log class
 *
 *	histroy
 * 		2014-08-06	Yuanjj		-	create
 */

#include <QDateTime>
#include <QDir>
#include "log.h"
#include "define.h"
#include "errorcode.h"
#include "routine/global.h"

cls_log::cls_log()
{
    _INIT_LOCK( &m_lock );
    m_file.clear();
}

cls_log::~cls_log()
{
    m_file.clear();
    _DEL_LOCK( &m_lock );
}

/**
 *	initialize log object
 *
 * 	return
 * 		==	0	successful
 * 		!=	0	errorcode
 */
pem_error_t cls_log::instance()
{
    pem_error_t		res = PEM_OK;
    opt_info		opt;
    QDir			dir;

    g_opt.get_opt( opt );
    dir.searchPaths( opt.g_path );
    dir.mkdir( "log" );

    _LOCK( &m_lock );
    _change_date();
    _UNLOCK( &m_lock );

    return res;
}

/**
 *	date need to be updated
 */
pem_void_t cls_log::_change_date()
{
    QDate			date = QDate::currentDate();
    opt_info		opt;

    g_opt.get_opt( opt );

    m_file.clear();
    m_file.sprintf( "%s/log/", opt.g_path );
    m_file 	+= date.toString("yyyy-MM-dd.log");
    m_date 	= date.toString("yyyyMMdd");
}

/**
 *	write a log into file
 *
 *	@level			[in] the log level
 *	@type			[in] the log type ( normal, warning or error )
 *	@who			[in] who write the log
 *	@format			[in] the log string format
 *	@...			[in] other arguments
 *
 */
pem_void_t cls_log::write( pem_s32_t level, pem_s32_t type, const pem_s8_t *who, const pem_s8_t *format, ... )
{
    pem_s8_t			logbuf[768];
    pem_s32_t			len;
    va_list				list;

    // check log level
    if ( level > g_opt.get_log_level() )
        return;

    // build log str
    va_start( list, format );
    len = vsnprintf( logbuf, sizeof(logbuf), format, list );
    va_end( list );

    if ( 0 >= len )
        return;

    if ( (signed)sizeof(logbuf) <= len )
    {
        len = sizeof(logbuf) - 1;
        logbuf[len] = '\0';
    }

    _LOCK( &m_lock );
    // write log into file
    _write( type, who, logbuf );
    _UNLOCK( &m_lock );
}

/**
 *	writting log
 *
 *	@type			[in] the log type ( normal, warning or error )
 *	@who			[in] who write the log
 * 	@log			[in] the log content buf
 */
pem_void_t cls_log::_write( pem_s32_t type, const pem_s8_t* who, const pem_s8_t *log )
{
    const pem_s8_t		*logtype[4]		= { "[info]", "[warn]", "[error]", "[unknow]" };
    QDateTime			datetime 		= QDateTime::currentDateTime();
    QString				logstr;
    QByteArray			ba;
    QFile				file;

    // check date changed
    if( m_date != datetime.date().toString( "yyyyMMdd" ) )
        _change_date();

    // build date time format
    ba = datetime.toString( "[yyyy-MM-dd HH:mm:ss]" ).toLatin1();
    logstr.sprintf( "%s%s <%s>: %s\n", logtype[type&0x3], ba.data(), who, log );

    // writting into file
    file.setFileName( m_file );
    if ( !file.open( QFile::Append | QFile::Text ) )
        return;

    ba = logstr.toLatin1();
    file.write( ba.data(), ba.size() );
    file.close();
}
